package com.ias.redis.config;

import com.ias.redis.support.CacheMessageListener;
import com.ias.redis.support.RedisCaffeineCacheManager;

import lombok.extern.slf4j.Slf4j;

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

import java.util.Objects;

@AutoConfiguration
@AutoConfigureAfter(RedisAutoConfiguration.class)
@EnableConfigurationProperties(CacheRedisCaffeineProperties.class)
@ConditionalOnProperty(prefix = "ias.cache.l2", name = "enabled", havingValue = "true", matchIfMissing = true)
@Slf4j
public class CacheRedisCaffeineAutoConfiguration {

    @Bean("L2_CacheManager")
    @ConditionalOnMissingBean(name = "L2_CacheManager")
    public RedisCaffeineCacheManager cacheManager(RedisTemplate<Object, Object> redisTemplate, 
                                                 CacheRedisCaffeineProperties cacheRedisCaffeineProperties) {
        log.info("[L2_CacheManager] init as SECONDARY cache manager.");
        return new RedisCaffeineCacheManager(cacheRedisCaffeineProperties, redisTemplate);
    }
    
    @Bean
    @ConditionalOnMissingBean(RedisMessageListenerContainer.class)
    public RedisMessageListenerContainer redisMessageListenerContainer(
            RedisTemplate<Object, Object> stringRedisTemplate, 
            RedisCaffeineCacheManager redisCaffeineCacheManager,
            CacheRedisCaffeineProperties cacheRedisCaffeineProperties) {
        RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
        redisMessageListenerContainer.setConnectionFactory(Objects.requireNonNull(stringRedisTemplate.getConnectionFactory()));
        CacheMessageListener cacheMessageListener = new CacheMessageListener(stringRedisTemplate, redisCaffeineCacheManager);
        redisMessageListenerContainer.addMessageListener(cacheMessageListener, new ChannelTopic(cacheRedisCaffeineProperties.getRedis().getTopic()));
        return redisMessageListenerContainer;
    }
}
